package com.lagou.handler;

import com.lagou.request.RpcRequest;
import com.lagou.service.UserServiceImpl;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.concurrent.EventExecutorGroup;
import jdk.nashorn.internal.ir.CallNode;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Map;

/**
 * 自定义的业务处理器
 */
@Component
@ChannelHandler.Sharable
public class RpcProcessHandler extends ChannelInboundHandlerAdapter implements ApplicationContextAware {

    private ApplicationContext ac;
    //当客户端读取数据时,该方法会被调用
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg instanceof RpcRequest) {
            RpcRequest request = (RpcRequest)msg;
            //通过容器获取bean对象
            //获取被请求的对象，通过反射调用
            Class clazz = Class.forName(request.getClassName());
            Map<String, Object> beanMap = ac.getBeansOfType(clazz);
            Object bean = null;
            for (Map.Entry<String, Object> entry : beanMap.entrySet()) {
                bean = entry.getValue();
            }
            //通过bean对象获取其调用的method反射对象
            Method method = bean.getClass().getMethod(request.getMethodName(), request.getParameterTypes());
            Object result = method.invoke(bean,request.getParameters());
            //获得结果值，放回请求对象中，写入
            if(result != null){
                request.setResult(result);
            }
            ctx.writeAndFlush(request);
        }
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.ac = applicationContext;
    }
}
